<?php

use Illuminate\Database\Capsule\Manager as DB;

class PayController extends CommonController
{
    protected $authExcept = ['prepay', 'notifyx', 'notifyr', 'alipay', 'joinPayNotify'];

    // 余额支付
    private function walletPay($order)
    {
        $order = DB::transaction(function () use ($order) {
            // 重新加锁读，防止连点问题
            $order = orderModel::where('id', $order->id)->lockForUpdate()->first();

            try {
                if ($order->total_fee > 0) {
                    memberModel::money(
                        -$order->total_fee,
                        $order->member_id,
                        'order',
                        $order->id,
                        '订单支付,订单编号:' . $order->order_sn
                    );
                }
            } catch (Exception $e){
                throw new Exception($e->getMessage());
            }

            // 支付后流程
            $user = memberModel::find($order->member_id);
            $notify = [
                'order_sn' => $order['order_sn'],
                'transaction_id' => '',
                'notify_time' => date('Y-m-d H:i:s'),
                'buyer_email' => $user->email ?? '',
                'pay_fee' => $order->total_fee,
                'pay_type' => 'wallet'             // 支付方式
            ];
            $order->paymentProcess($order, $notify);

            return $order;
        });

        json(['code' => 1, 'msg' => '支付成功', 'data' => $order]);
    }

    // 提货卡支付
    private function pickgoodscardPay($order)
    {
        DB::transaction(function () use ($order) {
            // 提货卡余额扣除
            $delivery_card_id = $order->ext_arr['pickgoods_card_id'] ?? 0;
            if ($delivery_card_id) {
                $member_card = \app\modules\Admin\models\memberpickgoodscardModel::find($delivery_card_id);
                if ($member_card) {
                    $before = $member_card->money;
                    if ($before < floatval($order->total_fee)) {
                        throw new Exception('用户提货卡余额不足');
                    }
                    $after = floatval(bcsub($before, $order->total_fee, 2));
                    DB::table('member_pickgoods_card')
                        ->where('id', $member_card->id)
                        ->update(['money' => $after]);
                    $member_pickgoods_log = [
                        'member_pickgoods_card_id' => $member_card->id,
                        'event' => 'pickgoods',
                        'event_id' => $order->id,
                        'before' => $before,
                        'money' => $order->total_fee,
                        'after' => $after,
                        'oper_type' => 'user',
                        'oper_id' => $order->member_id,
                    ];
                    DB::table('member_pickgoods_log')->insert($member_pickgoods_log);
                } else {
                    throw new Exception('用户提货卡不存在');
                }
            }
            $order->status = 1;
            $order->pay_type = 'pickgoods';
            $order->pay_fee = $order->total_fee;
            $order->paytime = time();
            $order->save();
        });

        json(['code' => 1, 'msg' => '支付成功', 'data' => $order]);
    }

    /**
     * 拉起支付
     */
    public function prepayAction()
    {
        // 查询用户
        $user = \app\service\auth::getUser();
        if ($user->status != 'normal') {
            throw new Exception("账号状态异常");
        }

        $order_sn = $this->getPost('order_sn');
        $payment = $this->getPost('payment');
        $terminal = $this->getPost('terminal');   // 终端： App、H5
        $openid = $this->getPost('openid', '');
        $paypwd = $this->getPost('paypwd') ?? null;
        $platform = getHeader('platform');

        $order = orderModel::nopay()->where('order_sn', $order_sn)->first();
        if (!$order) {
            throw new Exception("订单不存在");
        }
        if ($order->member_id != $user->id) {
            throw new Exception("不可支付该订单");
        }
        if (!$payment || !in_array($payment, ['wechat', 'alipay', 'wallet','joinpay', 'delivery_card'])) {
            throw new Exception("支付类型不能为空");
        }

        if (in_array($payment, ['wallet', 'delivery_card'])) {
            if (empty($user->pay_password)) {
                throw new Exception("请前往设置支付密码");
            }
            if($user->pay_password != md5($paypwd)) {
                throw new Exception('支付密码输入错误');
            }
            if ($payment == 'wallet') {
                // 余额支付
                $this->walletPay($order);
            } else {
                // 提货卡支付
                $this->pickgoodscardPay($order);
            }
            exit;
        }

        $order_data = [
            'subject' => '订单支付',
            'out_trade_no' => $order->order_sn,
            'amount' => $order->total_fee,
            // 'amount' => 0.01,
            'param' => json_encode(['order_id' => $order->id]),
        ];

        // 微信公众号，小程序支付，必须有 openid
        if ($payment == 'wechat') {
            if (in_array($platform, ['wxOfficialAccount', 'wxMiniProgram'])) {
                if (isset($openid) && $openid) {
                    // 如果传的有 openid
                    $order_data['openid'] = $openid;
                } else {
                    // 没有 openid 默认拿下单人的 openid
                    $oauth = memberoauthModel::Where('member_id', $order->member_id)
                        ->where('provider', 'Wechat')
                        ->where('platform', $platform)
                        ->first();
                    $order_data['openid'] = $oauth->openid ?? '';
                }

                if (empty($order_data['openid'])) {
                    // 缺少 openid
                    // throw new Exception("缺少 openid");
                    json(['code'=>1, 'data'=> 'no_openid']);
                    exit;
                }
            }

            $order_data['body'] = '商城订单支付';
        } else {
            $order_data['subject'] = '商城订单支付';
        }

        $wechat_config = \app\service\config::get('wechat');
        $notify_url = $wechat_config['notify_url'] ?? '';
        if (empty($notify_url)) {
            $notify_url = $this->config->application->hostUrl . "/pay/notifyx/payment/{$payment}/platform/{$platform}";
        }
        $pay = new PayService($payment, $platform, $notify_url);
        $result = $pay->create($order_data);

        $order_ext = json_decode($order->getRawOriginal('ext'), true) ?: [];
        $order_ext['pay_notify_url'] = $notify_url;
        $order->ext = json_encode($order_ext);
        $order->save();

        json(['code' => 1, 'msg' => '获取预付款成功', 'data' => [
            'pay_data' => $result,
            'pay_action' => $pay->method,
        ]]);
    }

    /**
     * 支付宝网页支付
     */
    public function alipayAction()
    {
        $order_sn = $this->request->get('order_sn');
        $order = Order::where('order_sn', $order_sn)->find();

        try {
            if (!$order) {
                throw new \Exception("订单不存在");
            }
            if ($order->status > 0) {
                throw new \Exception("订单已支付");
            }
            if ($order->status < 0) {
                throw new \Exception("订单已失效");
            }

            $notify_url = $this->request->root(true) . '/addons/shopro/pay/notifyx/payment/alipay/platform/H5';
            $pay = new \addons\shopro\library\PayService('alipay', 'url', $notify_url);

            $order_data = [
                'out_trade_no' => $order->order_sn,
                'total_fee' => $order->total_fee,
                'subject' => '商城订单支付',
            ];

            $result = $pay->create($order_data);

            $result = $result->getContent();

	        echo $result;
        } catch (\Exception $e) {
            echo $e->getMessage();
        }

        // $this->assign('result', $result);

        // return $this->view->fetch();
    }


    /**
     * 汇聚支付
     */
    public function joinPayAction()
    {
        $order_sn = $this->request->post('order_sn');
        $frpCode = $this->request->post('type');

        $order = Order::nopay()->where('order_sn', $order_sn)->find();
        if (!$order) {
            $this->error("订单不存在");
        }
        $order['frpCode'] = $frpCode;
        $joinPay = new JoinPay($frpCode);
        $data = $joinPay->pay($order);

        $this->success('', $data);
    }

    public function joinPayNotifyAction()
    {
        $data = $this->request->get();
        $frpCode = $this->request->param('type');
        $joinPay = new JoinPay($frpCode);
        echo $joinPay->notify($data);
    }


    /**
     * 支付成功回调
     */
    public function notifyxAction()
    {
        Log::out('notifyx-input:' . file_get_contents("php://input"), 'pay');

        $payment = $this->get('payment', 'wechat');
        $platform = $this->get('platform', 'wxOfficialAccount');
        Log::out('notifyx-params:payment-' . $payment . ';platform-' . $platform, 'pay');

        (new PayService($payment, $platform))->notify('orderModel', 'notifyProcess');

        // {    // 微信回调参数
        //     "appid":"wx39cd0799d4567dd0",
        //     "bank_type":"OTHERS",
        //     "cash_fee":"1",
        //     "fee_type":"CNY",
        //     "is_subscribe":"N",
        //     "mch_id":"1481069012",
        //     "nonce_str":"dPpcZ6AzCDU8daNC",
        //     "openid":"oD9ko4x7QMDQPZEuN8V5jtZjie3g",
        //     "out_trade_no":"202010240834057843002700",
        //     "result_code":"SUCCESS",
        //     "return_code":"SUCCESS",
        //     "sign":"3103B6D06F13D2B3959C5B3F7F1FD61C",
        //     "time_end":"20200407102424",
        //     "total_fee":"1",
        //     "trade_type":"JSAPI",
        //     "transaction_id":"4200000479202004070804485027"
        // }

        // {    // 支付宝支付成功回调参数
        //     "gmt_create":"2020-04-10 19:15:00",
        //     "charset":"utf-8",
        //     "seller_email":"xptech@qq.com",
        //     "subject":"\u5546\u57ce\u8ba2\u5355\u652f\u4ed8",
        //     "sign":"AOiYZ1a2mEMOuIbHFCi6V6A0LJ97UMiHsCWgNdSU9dlzKFl15Ts8b0mL\/tN+Hhskl+94S3OUiNTBD3dD0Kv923SqaTWxNdj533PCdo2GDKsZIZgKbavnOvaccSKUdmQRE9KtmePPq9V9lFzEQvdUkKq1M8KAWO5K9LTy2iT2y5CUynpiu\/04GVzsTL9PqY+LDwqj6K+w7MgceWm1BWaFWg27AXIRw7wvsFckr3k9GGajgE2fufhoCYGYtGFbhGOp6ExtqS5RXBuPODOyRhBLpD8mwpOX38Oy0X+R4YQIrOi02dhqwPpvw79YjnvgXY3qZEQ66EdUsrT7EBdcPHK0Gw==",
        //     "buyer_id":"2088902485164146",
        //     "invoice_amount":"0.01",
        //     "notify_id":"2020041000222191501064141414240102",
        //     "fund_bill_list":"[{\"amount\":\"0.01\",\"fundChannel\":\"PCREDIT\"}]",
        //     "notify_type":"trade_status_sync",
        //     "trade_status":"TRADE_SUCCESS",
        //     "receipt_amount":"0.01",
        //     "buyer_pay_amount":"0.01",
        //     "app_id":"2021001114666742",
        //     "sign_type":"RSA2",
        //     "seller_id":"2088721922277739",
        //     "gmt_payment":"2020-04-10 19:15:00",
        //     "notify_time":"2020-04-10 19:15:01",
        //     "version":"1.0",
        //     "out_trade_no":"202007144778322770017000",
        //     "total_amount":"0.01",
        //     "trade_no":"2020041022001464141443020240",
        //     "auth_app_id":"2021001114666742",
        //     "buyer_logon_id":"157***@163.com",
        //     "point_amount":"0.00"
        // }

        // {   // 支付宝退款成功（交易关闭）回调参数
        //     "gmt_create": "2020-08-15 14:48:32",
        //     "charset": "utf-8",
        //     "seller_email": "xptech@qq.com",
        //     "gmt_payment": "2020-08-15 14:48:32",
        //     "notify_time": "2020-08-15 16:11:45",
        //     "subject": "商城订单支付",
        //     "gmt_refund": "2020-08-15 16:11:45.140",
        //     "sign": "b6ArkgzLIRteRL9FMGC6i\/jf6VwFYQbaGDGRx002W+pdmN5q9+O4edZ3ALF74fYaijSl9ksNr0dKdvanu3uYxBTcd\/GIS4N1CWzmCOv6pzgx5rO\/YvGoHLM3Yop0GKKuMxmnNsZ6jhYKEY7SYD3Y0L6PU9ZMdHV7yIiVj+zZmbKzUgK9MPDCEXs+nzpNAiSM8GTqYRSUvKobAK68hswG2k1QIcqr5z+ZmVYa\/nHHkoC9qXt5zwyGi4P+2eOsr6V2PjA3x8qqe7TN5aI1DeoZD5KqHPYYaYF17J2q6YPlgl3WUl1RhE7H86bivB1fIuYEv\/3+JR74WN\/o7krGw1RPHg==",
        //     "out_biz_no": "R202004114414846255015300",
        //     "buyer_id": "2088902485164146",
        //     "version": "1.0",
        //     "notify_id": "2020081500222161145064141453349793",
        //     "notify_type": "trade_status_sync",
        //     "out_trade_no": "202002460317545607015300",
        //     "total_amount": "0.01",
        //     "trade_status": "TRADE_CLOSED",
        //     "refund_fee": "0.01",
        //     "trade_no": "2020081522001464141438570535",
        //     "auth_app_id": "2021001114666742",
        //     "buyer_logon_id": "157***@163.com",
        //     "gmt_close": "2020-08-15 16:11:45",
        //     "app_id": "2021001114666742",
        //     "sign_type": "RSA2",
        //     "seller_id": "2088721922277739"
        // }
    }


    /**
     * 退款成功回调
     */
    public function notifyrAction()
    {
        Log::out('notifyr-comein:', 'pay');
        Log::out('notifyr-input:' . file_get_contents("php://input"), 'pay');
    }


    private function refundFinishAction($out_trade_no, $out_refund_no)
    {
        $order = Order::where('order_sn', $out_trade_no)->find();
        $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();

        if (!$order || !$refundLog || $refundLog->status != 0) {
            // 订单不存在，或者订单已退款
            return true;
        }

        $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find();

        Db::transaction(function () use ($order, $item, $refundLog) {
            \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog);
        });

        return true;
    }
}
